﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.GamerServices;

namespace FuncWorks.Xna.Input
{
	public class DrumKit
	{
		#region Instance Fields
		public PlayerIndex Index { get; private set; }
		public string Name { get; private set; }
		GamePadState lastState;
		public GamePadState State { get; private set; }

		public bool Red { get; private set; }
		public bool Yellow { get; private set; }
		public bool Blue { get; private set; }
		public bool Orange { get; private set; }
		public bool Green { get; private set; }
		public bool Pedal { get; private set; }

		public float MagnitudeRed { get; private set; }
		public float MagnitudeBlue { get; private set; }
		public float MagnitudePedal { get; private set; }
		#endregion

		#region Static Fields
		public static DrumKitCollection ActiveKits { get; private set; }
		#endregion

		public DrumKit(PlayerIndex playerIndex)
		{
			// Set variables
			Index = playerIndex;
			State = lastState = GamePad.GetState(playerIndex);

			// Get profile information
			if (Gamer.SignedInGamers[playerIndex] != null) { Name = Gamer.SignedInGamers[playerIndex].Gamertag; }
			else
			{
				switch (playerIndex)
				{
					case PlayerIndex.One: Name = "Player 1"; break;
					case PlayerIndex.Two: Name = "Player 2"; break;
					case PlayerIndex.Three: Name = "Player 3"; break;
					case PlayerIndex.Four: Name = "Player 4"; break;
					default: Name = ""; break;
				}
			}
		}

		public static DrumKit[] Discover()
		{
			if (ActiveKits == null) { ActiveKits = new DrumKitCollection(); }

			List<DrumKit> results = new List<DrumKit>();

			foreach (PlayerIndex index in new PlayerIndex[] { PlayerIndex.One, PlayerIndex.Two, PlayerIndex.Three, PlayerIndex.Four })
			{
				if (ActiveKits.Count(x => x.Index == index) > 0) { continue; }
				GamePadCapabilities caps = GamePad.GetCapabilities(index);
				if (caps.IsConnected && caps.GamePadType == GamePadType.DrumKit)
				{
					DrumKit kit = new DrumKit(index);
					ActiveKits.Add(kit);
					results.Add(kit);
				}
			}

			return results.ToArray();
		}

		public static DrumKit[] Purge()
		{
			DrumKit[] results = (from k in ActiveKits where !k.State.IsConnected select k).ToArray<DrumKit>();
			foreach (DrumKit drumKit in results) { ActiveKits.Remove(drumKit); }
			return results;
		}

		protected bool CatchHit(Buttons button)
		{
			return lastState.IsButtonUp(button) && State.IsButtonDown(button);
		}

		public void Update()
		{
			State = GamePad.GetState(Index);

			if (State.IsConnected)
			{
				Red = CatchHit(Buttons.B);
				Yellow = CatchHit(Buttons.Y);
				Blue = CatchHit(Buttons.X);
				Orange = CatchHit(Buttons.RightShoulder);
				Green = CatchHit(Buttons.A);
				Pedal = CatchHit(Buttons.LeftShoulder);
				MagnitudeRed = State.ThumbSticks.Left.Y;
				MagnitudeBlue = State.ThumbSticks.Right.X;
				MagnitudePedal = State.ThumbSticks.Right.Y;
			}
			else
			{
				Red = Yellow = Blue = Orange = Green = Pedal = false;
				MagnitudeRed = MagnitudeBlue = MagnitudePedal = 0;
			}

			lastState = State;
		}
	}
}
